import constant
import utils  # 导入整个utils模块
from flask import Flask, render_template, request, jsonify, send_from_directory
import pandas as pd
import chardet
import numpy as np
import os
import time

app = Flask(__name__)

# 配置静态文件目录
app.static_folder = 'static'
err_html = 'designing.html'

# 专门处理favicon.ico请求的路由
@app.route('/favicon.ico')
def favicon():
    return send_from_directory(os.path.join(app.root_path, app.static_folder),
                               'favicon.ico',
                               mimetype='image/vnd.microsoft.icon')

@app.route('/')
# 主页路由
def index():
    return render_template('index.html')

@app.route('/termsOfUse')
# 使用条款路由
def terms():
    return  render_template('termsOfUse.html')

@app.route('/visualization')
# 数据可视化路由
def visualization():
    return  render_template(err_html)

@app.route('/reports')
# 报表中心路由
def reports():
    return  render_template(err_html)

@app.route('/helper')
# 工具助手路由
def helper():
    return render_template('helper.html')

@app.route('/settings')
# 系统设置路由
def settings():
    return  render_template(err_html)

@app.route('/feedbackPage')
# 用户反馈路由
def feedbackPage():
    return render_template('feedbackPage.html')

@app.route('/err')
# 开发中页面路由
def err():
    return render_template(err_html)

@app.route('/test',methods=['POST','GET'])
# 用于测试的路由页面
def test():
    return render_template('test.html')

@app.route('/tagRecord')
# 标注记录工具路由
def tagRecord():
    return render_template('tagRecord.html')


# 提供base基础数据的API路由
@app.route('/base', methods=['GET'])
def base_data():
    # 要返回的初始数据
    initial_info = {
        "version_info": utils.notice_csv2dict(constant.init_data_url).get("version_info"),
        "notice_info": utils.notice_csv2dict(constant.init_data_url).get("notice_info"),
        "terms_version": utils.notice_csv2dict(constant.init_data_url).get("terms_version")
    }
    # 返回JSON数据（注意这里用jsonify而非render_template）
    return jsonify(initial_info)


# 存储用户最后提交反馈的时间戳（邮箱 -> 时间戳）
last_submit_times = {}
@app.route('/feedback', methods=['POST','GET'])
def feedback():
    try:
        # 获取JSON数据
        data = request.get_json()
        if not data:
            return jsonify({'error': '未收到数据，请检查请求格式'}), 400

        # 提取字段
        subject = data.get('subject', '')
        email = data.get('email', '')
        name = data.get('name', '')
        content = data.get('content', '')

        # 验证必填字段
        if not all([subject, email, content]):
            return jsonify({'error': '主题、邮箱和内容为必填项'}), 400

        # 检查同一用户10分钟内是否重复提交
        current_time = time.time()  # 获取当前时间戳（秒）
        set_time = 60
        if email in last_submit_times:
            time_diff = current_time - last_submit_times[email]
            if time_diff < set_time:  # 10分钟 = 600秒
                remaining_time = int(set_time - time_diff)
                return jsonify({
                    'error': f'请勿频繁提交反馈，请{remaining_time}秒后再试'
                }), 400

        # 处理数据
        print(f"===>收到反馈：{name} <{email}>，主题：{subject}\n内容：{content}\n")

        print("发送邮件开始")
        utils.send_feedback_notice(email, subject, name)

        # 更新用户最后提交时间
        last_submit_times[email] = current_time

        # 日志
        action_str = utils.operation_log(constant.Actions.SUBMIT_FEEDBACK_SUCCESSFULLY.value, 1)
        utils.write_to_log(action_str)

        # 返回包含时间戳的成功响应
        return jsonify({
            'success': True,
            'message': '反馈已收到，感谢您的支持！',
            'timestamp': current_time  # 返回当前时间戳
        })

    except Exception as e:
        # 日志
        action_str = utils.operation_log(constant.Actions.SUBMIT_FEEDBACK_SUCCESSFULLY.value, 0)
        utils.write_to_log(action_str)
        return jsonify({'error': f'处理失败：{str(e)}'}), 500




@app.route('/calculate', methods=['POST'])
# 数据处理逻辑
def calculate():
    try:
        # 获取上传的文件
        file = request.files['file']

        # 检查文件类型
        file_ext = os.path.splitext(file.filename)[1].lower()
        if file_ext not in ['.csv', '.xlsx']:
            return jsonify({'error': '请上传CSV或XLSX格式的文件'})

        # 读取文件
        if file_ext == '.csv':
            # 检测文件编码
            raw_data = file.stream.read()
            result = chardet.detect(raw_data)
            encoding = result['encoding'] or 'utf-8'

            # 使用检测到的编码重新读取文件，设置low_memory=False以避免混合类型警告
            file.stream.seek(0)  # 重置文件指针
            df = pd.read_csv(file, encoding=encoding, low_memory=False)
        else:
            df = pd.read_excel(file)


        # 检查必要列是否存在
        if ('操作名称' not in df.columns) or ('实际工作时长' not in df.columns) or ('工作量1' not in df.columns) or ('工作量3' not in df.columns):
            return jsonify({'error': '表格中缺少列:"操作名称"/"实际工作时长"/"工作量1"/"工作量2"'})

        # 获取工时数据
        regular_hours = float(request.form['regularHours'])
        overtime_hours = float(request.form['overtimeHours'])
        non_production_hours = float(request.form['nonProductionHours'])

        # 当日总工时
        total_working_hours = regular_hours + overtime_hours + non_production_hours

        # 筛选合格-通过和不合格-驳回的数据，并显式复制
        filtered_df = df[df['操作名称'].isin(['合格-通过', '不合格-驳回','提交','跳过'])].copy()

        # 确保实际工作时长列是数值类型
        filtered_df['实际工作时长'] = pd.to_numeric(filtered_df['实际工作时长'], errors='coerce')
        # 确保工作量1列是数值类型
        filtered_df['工作量1'] = pd.to_numeric(filtered_df['工作量1'], errors='coerce')
        # 确保工作量2列是数值类型
        filtered_df['工作量2'] = pd.to_numeric(filtered_df['工作量2'], errors='coerce')

        # 计算筛选后的帧数，排出无效值
        # 方法1：使用shape属性，shape[0]表示行数
        frame_rate = filtered_df.shape[0]

        # 计算选后的元素（框）工作量，跳过NaN值
        total_element = filtered_df['工作量1'].sum(skipna=True) + filtered_df['工作量2'].sum(skipna=True)

        # 计算筛选后的数据总和（秒），跳过NaN值
        total_seconds = filtered_df['实际工作时长'].sum(skipna=True)

        # 转换为小时
        qualified_hours = total_seconds / 3600

        # 计算有产出的总工时
        total_hours = regular_hours + overtime_hours

        # 计算效率值
        efficiency = qualified_hours / total_hours if total_hours > 0 else 0

        # 结果保留4位小数（四舍五入）
        efficiency_rounded = round(efficiency, 4)

        # 转换为百分比
        efficiency_percentage = f"{efficiency_rounded * 100:.2f}%"

        # 计算实际工作时间，结果保留2位小数（四舍五入）
        qualified_hours = round(qualified_hours, 2)


        # 准备要返回的数据
        result = {
            'qualified_hours': qualified_hours,
            'total_hours': total_hours,
            'efficiency': efficiency_rounded,
            'efficiency_percentage': efficiency_percentage,
            'frame_rate': frame_rate,
            'total_element': total_element,
            'total_working_hours': total_working_hours
        }


        # 在返回响应前处理数据
        def process_response_data(data):
            # 转换numpy数据类型为Python原生类型
            processed = {}
            for key, value in data.items():
                if isinstance(value, np.integer):
                    processed[key] = int(value)
                elif isinstance(value, np.floating):
                    processed[key] = float(value)
                elif isinstance(value, np.ndarray):
                    processed[key] = value.tolist()
                else:
                    processed[key] = value
            return processed

        # 日志
        action_str = utils.operation_log(constant.Actions.CALCULATE_WORKING_HOURS.value, 1)
        utils.write_to_log(action_str)

        # 返回结果
        return jsonify(process_response_data(result))


    except Exception as e:
        # 日志
        action_str = utils.operation_log(constant.Actions.CALCULATE_WORKING_HOURS.value,0)
        utils.write_to_log(action_str)
        return jsonify({'error': f'处理请求时发生错误: {str(e)}'})


if __name__ == '__main__':
    app.run(debug=True ,host='0.0.0.0' ,port=5000)